#ifndef _OPENGLAPPFRAMEWORK_CAMERA_H_
#define _OPENGLAPPFRAMEWORK_CAMERA_H_

#include "OpenglAppFramework/inc/OpenglEnv.h"
#include "OpenglAppFramework/inc/PlugIn/PlugIn.h"
#include "OpenglAppFramework/inc/glm/glm.hpp"

enum class ProjectionType {
    Perspective,
    Orth
};

class Shader;
class Camera : public PlugIn {
public:
    Camera(const std::string& name);
    ~Camera();

    // 向量不必归一化
    // void setLookAtInfo(const glm::vec3& front_vec, const glm::vec3& up_vec, ProjectionType type);
    // void setProjMat(const glm::mat4& m);
    void uploadShaderData(Shader* shader) override;
    // void uploadPorjectionMat(Shader* shader);
    // void uploadViewMat(Shader* shader);

    int setConfigData(const nlohmann::json& data) override;
    int init() override;
    void destroy() override;
    void routine() override;
    const glm::mat4& getProjMat() const;
    const glm::mat4& getViewMat() const;
    void setFrontVec(const glm::vec3& front_vec);

    // static void MouseCallback(GLFWwindow* , double x, double y);
    // static void ScrollCallback(GLFWwindow* , double x, double y);

private:
    ProjectionType m_proj_type;
    glm::vec3 m_up_vec;
    glm::vec3 m_front_vec; // 静态回调函数要用到
    float m_near;
    float m_far;
    float m_fovy;   // 投影椎体的观察角（degree）
    float m_aspect; // 视口width/height
    float m_up, m_down, m_left, m_right;

    bool m_enable_asdw, m_enable_mouse;
    glm::mat4 m_proj_mat;
    glm::mat4 m_lookat_mat;
    float m_cam_speed;

    class MouseInfo {
    public:
        double last_x, last_y;
        double cur_x, cur_y;
        double sensitivity = 0.1;
        double yaw = -90.0;
        double pitch = 0.0;
        double fov = 45.0;
        bool is_first = true;
    };
    MouseInfo m_mouse_info;
};

#endif//_OPENGLAPPFRAMEWORK_CAMERA_H_
